#!/usr/bin/env node

var express = require('express');
var path = require('path');
var fs = require('fs');
var bodyParser = require('body-parser');
var multer = require('multer');

var http = require('http');
var https = require("https");
var os = require("os");

var cors = require('cors')

const log4js = require('log4js');

const { argv } = require('yargs')

const history = require('connect-history-api-fallback');

log4js.configure({
	appenders: {
		system: {
			type: 'file',
			filename: path.join(__dirname, 'log/system.log'),
		},
		logger: {
			type: 'file',
			filename: path.join(__dirname, 'log/logger.log'),
		},
		mock: {
			type: 'file',
			filename: path.join(__dirname, 'log/mock.log'),
		},
		websocket: {
			type: 'file',
			filename: path.join(__dirname, 'log/websocket.log'),
		},
		console: {
			type: "console"
		},
	},
	categories: {
		default: {
			appenders: ['system', 'console'],
			level: 'debug'
		},
		logger: {
			appenders: ['logger', 'console'],
			level: 'debug'
		},
		websocket: {
			appenders: ['websocket', 'console'],
			level: 'debug'
		},
		mock: {
			appenders: ['mock', 'console'],
			level: 'debug'
		}
	}
});
const logger = log4js.getLogger();

// const args = process.argv.slice(2);
const custom_root = argv._.join(" ");
var original_root = custom_root || process.cwd(); // 保存原始的工作目录
var original_dir = original_root;
var original_file = "";
if (fs.statSync(original_root).isFile()) {
	original_dir = path.dirname(original_root);
	original_file = path.basename(original_root);
}

logger.info(`original_dir: ${original_dir} original_file: ${original_file}`);

process.chdir(__dirname);



/*---自定义组件---*/
//上传文件demo
const uploadFile = require("./submodules/node_http_server_lib/upload_file");
//静态文件服务器
const staticServer = require("./submodules/node_http_server_lib/static_server");
// 图片生成服务器
const image_generator = require("./submodules/node_http_server_lib/image_generator");
// mock 服务器
const mock = require("./submodules/node_http_server_lib/mock");
// markdown 服务器
const markdown_server = require("./submodules/node_http_server_lib/markdown_server");
const websocket_server = require("./submodules/node_http_server_lib/websocket-server");
const logger_server = require("./submodules/node_http_server_lib/logger");
const system_server = require("./submodules/node_http_server_lib/system");


require("./submodules/node_http_server_lib/case_sensitive_static.js")(express, argv.case_sensitive != 0, argv.download);

var app = express();

if (argv.history) {
	app.use(history());
}

// 配置跨域请求
app.use(cors());
app.use(bodyParser.json()); // for parsing application/json
app.use(bodyParser.urlencoded({ extended: true })); // for parsing application/x-www-form-urlencoded
// app.use(multer()); // for parsing multipart/form-data

//由于是访问1024以下端口，在mac osx 或者 linux系统中，要使用 sudo 运行
var HTTP_PORT = argv.http_port;
var HTTPS_PORT = argv.https_port;
var IS_DEBUG = parseInt(argv.debug) || false;
app['__IS_DEBUG__'] = IS_DEBUG;
var localIP = "localhost";
var ifaces = os.networkInterfaces();
const availableIPs = Object.values(ifaces).flat().reduce((prev, iface) => {
	if ('IPv4' !== iface.family || iface.internal !== false) {
		// skip over internal (i.e. 127.0.0.1) and non-ipv4 addresses
		return prev;
	}
	prev.push(iface.address);
	return prev;
}, [])

if (argv.export && availableIPs.length > 0) {
	localIP = availableIPs[availableIPs.length - 1];
}
const defaultIpPatten = ["127.0.0.1", ...availableIPs].join("|");


var privateKey;
var certificate;
try {
	privateKey = fs.readFileSync('./crt/private.pem', 'utf8');
} catch (e) {
	console.warn('read ./crt/private.pem failed');
}
try {
	certificate = fs.readFileSync('./crt/file.crt', 'utf8');
} catch (e) {
	console.warn('read ./crt/file.crt failed');
}
var credentials = { key: privateKey, cert: certificate };

var httpServer = http.createServer(app);
var httpsServer = https.createServer(credentials, app);


// 注册 文件上传demo
const uploadFolder = argv.upload_folder || path.join(__dirname, "upload");
fs.mkdirSync(uploadFolder, { recursive: true });
uploadFile(app, argv.upload_prefix, uploadFolder);
// 注册 图片获取服务器
image_generator(app, argv.image_prefix);
// 日志服务器
logger_server(app, argv.logger_prefix);
// markdown服务器
markdown_server(app, argv.markdown_prefix, argv.markdown_dir || path.join(__dirname, "md"));
// 注册 mock 服务器
mock(app, argv.mock_prefix);
system_server(app, argv.system_prefix);
httpServer.listen(HTTP_PORT, "0.0.0.0", function () {
	HTTP_PORT = httpServer.address().port;
	console.log('http server listening on %s:%s', localIP, HTTP_PORT);
	// 静态服务器要在最后注册，否则，无法接收 POST 请求
	staticServer(app, localIP, original_dir, original_file, HTTP_PORT, parseInt(argv.disable_serve_index), argv.valid_pattern || argv.url_pattern, argv.ip_pattern || defaultIpPatten, argv.downloadable);
});
if (HTTPS_PORT) {
	httpsServer.listen(HTTPS_PORT, "0.0.0.0", function () {
		HTTPS_PORT = httpsServer.address().port;
		console.log('https server listening on %s:%s', localIP, HTTPS_PORT);
	});
}
// var server = app.listen(PORT, function(){
//     console.log('Server listening on %s', PORT);
// });

// 提供给websocket用的http-server
(() => {
	let WS_PORT = argv.ws_port;
	let WSS_PORT = argv.wss_port;
	let reqListener = function (request, response) {
		console.log((new Date()) + ' Received request for ' + request.url);
		response.writeHead(404);
		response.end();
	};
	let httpServer = http.createServer(reqListener);
	let httpsServer = https.createServer(credentials, reqListener);
	if (WS_PORT) {
		httpServer.listen(WS_PORT, "0.0.0.0", function () {
			console.log('ws server listening on %s:%s', localIP, WS_PORT);
		});
	}
	if (WSS_PORT) {
		httpsServer.listen(WSS_PORT, "0.0.0.0", function () {
			console.log('wss server listening on %s:%s', localIP, WSS_PORT);
		});
		websocket_server(httpsServer);
	}
	if (WS_PORT || WSS_PORT) {
		websocket_server(httpServer);
	}
})();

